package com.xiang.sql.service;

import java.util.Arrays;
import java.util.List;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xiang.api.Util;
import com.xiang.sql.entity.User;
import com.xiang.sql.StaticSql;
import com.xiang.sql.entity.OrderStock;
import com.xiang.sql.entity.StockLog;
import com.xiang.sql.mapper.OrderStockMapper;

/**
 * 单据 服务类
 * 
 * @author mac-xiang
 */
@Service
public class OrderStockService extends ServiceImpl<OrderStockMapper, OrderStock> {
  @Resource
  OrderStockMapper mapper;
  public static final String[] types = { "入库单", "出库单", "调拨单", "补货单", "配货单" };

  private QueryWrapper<OrderStock> readWrapper(JSONObject p, User per) {
    QueryWrapper<OrderStock> ret = Util.getQuery(p, OrderStock.class, "a");
    if (per != null && !per.per("单据查询")) {
      ret.and(e -> {
        e.eq("a.`create`", per.id).or().eq("a.in_gid", per.gid).or().eq("a.out_gid", per.gid);
      });
    }
    return ret;
  }

  private List<OrderStock> getList(QueryWrapper<OrderStock> q) {
    List<OrderStock> ret = mapper.selectList2(q);
    ret.forEach(e -> {
      e.content = StaticSql.service.stockLog.getByOid(e.id);
    });
    return ret;
  }

  private List<OrderStock> getList(JSONObject p, User per) {
    return getList(readWrapper(p, per));
  }

  private final static String limit = " LIMIT %d,%d";

  private Page<OrderStock> getPage(Page<OrderStock> page, JSONObject p, User per) {
    QueryWrapper<OrderStock> q = readWrapper(p, per);
    page.setTotal(mapper.count(q));
    final long c = page.getCurrent(), s = page.getSize();
    List<OrderStock> d = getList(readWrapper(p, per).last(String.format(limit, s * (c - 1), s)));

    page.setRecords(d);
    return page;
  }

  public void checkCreate(OrderStock os, User per) {
    os.id = Util.sGetId();
    if (os.redress == null) {
      os.redress = "";
    }
    os.createTime = Util.time();
    os.sendTime = 0l;
    os.recvTime = 0l;
    os.create = per.id;
    if (os.name == null) {
      os.name = "";
    }

    os.money = 0;
    StaticSql.service.stockLog.check(os.content, per.id, os.id, os.inGid, os.outGid);
    if (Util.includes(types, os.type) < 0) {
      throw new RuntimeException("单据类型错误");
    }
    if (!per.per(os.type + "创建")) {
      throw new RuntimeException("没有权限:" + os.type + "创建");
    }
    if (os.des == null) {
      os.des = "";
    }
  }

  public OrderStock create(JSONObject p, User per) {
    if (per != null) {
      OrderStock entity = Util.getEntity(p, OrderStock.class);
      checkCreate(entity, per);
      String sql = String.format("%s\n%s", Util.insertSql(
          Arrays.asList(entity), OrderStock.class),
          Util.insertSql(entity.content, StockLog.class));
      System.out.println(sql);
      StaticSql.run.safeQuery(sql);
      return entity;
    }
    throw new RuntimeException("没有权限");
  }

  public Object read(JSONObject p, User per) {
    Page<OrderStock> page = Util.getPage(p, OrderStock.class);
    return page == null ? getList(p, per) : getPage(page, p, per);
  }

  public int delete(JSONObject p, User per) {
    if (per != null && per.per("单据删除")) {
      QueryWrapper<OrderStock> q = Util.getQuery(p, OrderStock.class).eq("send_time", 0);
      if (this.count(q) > 10) {
        throw new RuntimeException("删除数据的数量不能超过10条");
      }
      return mapper.delete(q);
    }
    throw new RuntimeException("没有权限");
  }

  public long count(JSONObject p, User per) {
    return this.count(readWrapper(p, per));
  }

  public boolean have(String id, User per) {
    QueryWrapper<OrderStock> q = new QueryWrapper<OrderStock>().eq("id", id);
    q.and(e -> {
      e.or().eq("`create`", per.id).or().eq("in_gid", per.gid).or().eq("out_gid", per.gid);
    });
    return this.count(q) == 1;
  }

  private final String sendSql = "UPDATE `order_stock` SET `send_time`=%d WHERE id='%s';\n";
  private final String recvSql = "UPDATE `order_stock` SET `recv_time`=%d WHERE id='%s';\n";

  public int send(JSONObject p, User per) {
    int ret = 0;
    List<OrderStock> l = mapper.selectList2(readWrapper(p, per));
    boolean b = per.per("强制发货");
    final long time = Util.time();
    StringBuilder sql = new StringBuilder();
    for (OrderStock e : l) {
      if (b || e.outGid.equals(per.gid) || e.create.equals(per.id)) { // 商家发货
        sql.append(StaticSql.service.stockLog.send(e.id));
        sql.append(String.format(sendSql, time, e.id));
        ret++;
      }
    }
    StaticSql.run.safeQuery(sql.toString());
    return ret;
  }

  public int recv(JSONObject p, User per) {
    int ret = 0;
    List<OrderStock> l = mapper.selectList2(readWrapper(p, per));
    boolean b = per.per("强制收货");
    final long time = Util.time();
    StringBuilder sql = new StringBuilder();
    for (OrderStock e : l) {
      if (b || e.inGid.equals(per.gid)) { // 商家收货
        sql.append(StaticSql.service.stockLog.recv(e.id));
        sql.append(String.format(recvSql, time, e.id));
        ret++;
      }
    }
    StaticSql.run.safeQuery(sql.toString());
    return ret;
  }
}
